#ifndef _H_UART_BUS_
#define _H_UART_BUS_

#include "stm32f4xx.h"
#include <RTL.h>

#include "control_command.h"

#define nlUARTBUFF				256

enum {
		UARTBUS_STM32F4XX_UART1,
		UARTBUS_STM32F4XX_UART2,
		UARTBUS_STM32F4XX_UART4,
		UARTBUS_STM32F4XX_UART6,
		nlUARTBUS
};

struct tagUartInfo {
		uint32_t     fBaud;
		uint8_t      nlbits;
		BOOL stopbit;
		uint8_t check;		//even parity 
};


struct tagUartAgreement {
		struct tagUartBus *uartbus;
		void (*tx_handler)(struct tagUartBus *,void *);
		void (*rx_handler)(struct tagUartBus *,void *);
		void *prag;
		uint8_t *box;
};

struct tagUartBus {
		OS_SEM semaphore;
		struct tagUartInfo info;
		struct tagUartOperate *operate;
		struct tagUartAgreement *agreement;
		void *privatedata;		
};

struct tagUartOperate {
		void (*initialize)(struct tagUartBus *);
		void (*control)(struct tagUartBus *,const uint32_t,const uint32_t,void *);

		void (*tx_En)(struct tagUartBus *);
		void (*tx_Dis)(struct tagUartBus *);
		void (*rx_En)(struct tagUartBus *);
		void (*rx_Dis)(struct tagUartBus *);

		void (*write_byte)(struct tagUartBus *,const uint8_t);
		uint8_t (*read_byte)(struct tagUartBus *);
		BOOL (*tx_isend)(struct tagUartBus *);
};

extern struct tagUartBus *UarBus[];
extern const uint32_t get_uartbus_nl;

extern void UartBus_Init(void);

static __INLINE void UartBus_Control(struct tagUartBus *pUb,const uint32_t command,const uint32_t parameter,void *prag)
{
		if (pUb)
		if (pUb->operate->control) {
				pUb->operate->control(pUb,command,parameter,prag);		
		}
}

extern int UartBus_LinkAgreement(struct tagUartBus *pUb,struct tagUartAgreement *pUagr,const uint16_t timeout);

extern void UartBus_UnLinkAgreement(struct tagUartBus *pUb,struct tagUartAgreement *pUagr);

static __INLINE void UartBus_TxEn(struct tagUartBus *pUb)
{
		if (pUb->operate->tx_En) {
				pUb->operate->tx_En(pUb);
		}		
}

static __INLINE void UartBus_TxDis(struct tagUartBus *pUb)
{
		if (pUb->operate->tx_Dis) {
				pUb->operate->tx_Dis(pUb);
		}	
}

static __INLINE void UartBus_RxEn(struct tagUartBus *pUb)
{
		if (pUb->operate->rx_En) {
				pUb->operate->rx_En(pUb);
		}	
}

static __INLINE void UartBus_RxDis(struct tagUartBus *pUb)
{
		if (pUb->operate->rx_Dis) {
				pUb->operate->rx_Dis(pUb);
		}	
}

static __INLINE void UartBus_Write(struct tagUartBus *pUb,const uint8_t data)
{
		if (pUb->operate->write_byte) {
				pUb->operate->write_byte(pUb,data);		
		}
}

static __INLINE uint8_t UartBus_Read(struct tagUartBus *pUb)
{
		if (pUb->operate->read_byte) {
				return pUb->operate->read_byte(pUb);
		}
		return 0;
}

static __INLINE BOOL UartBus_Tx_IsEnd(struct tagUartBus *pUb)
{
		if (pUb->operate->tx_isend) {
				return pUb->operate->tx_isend(pUb);		
		}
		return 1;
}


extern struct tagUartBus stm32f4xx_uart[];
#define _DLY_R_TO_T()				os_dly_wait (1)

#endif
